home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / util / libs / queue.lzh / queue_2.0 / queue_test.c < prev    next >
C/C++ Source or Header  |  1996-10-09  |  7KB  |  328 lines

  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <proto/exec.h>
  8. #include <proto/dos.h>
  9.  
  10. #include "queue.h"
  11.  
  12. #include "queue_library.h" /* so we can look at internals */
  13.  
  14. #if 1
  15. #define LISTEN_REOPEN
  16. #define SEND_REOPEN
  17. #endif
  18.  
  19. #if defined (__GNUC__)
  20. #include "queue_inline.h"
  21. #elif defined (__SASC_60)
  22. #include "queue_pragmas.h"
  23. #endif
  24.  
  25. #if !defined (__SASC_60)
  26. struct ExecBase *SysBase = NULL;
  27. struct DosLibrary *DOSBase = NULL;
  28. #endif
  29. struct Library *QueueBase = NULL;
  30.  
  31. ULONG sigbit = -1;
  32.  
  33. typedef struct {
  34.   QMessage qmsg;
  35.   ULONG    pid;
  36. } MyQMessage;
  37.  
  38. void
  39. Block (int *abort)
  40. {
  41.   int r;
  42.  
  43.   if (r = rand () % 3)
  44.     Delay (r * 5);
  45.   if (SetSignal (0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  46.     *abort = 1;
  47. }
  48.  
  49. void
  50. cleanup (void)
  51. {
  52.   if (sigbit != -1)
  53.   {
  54.     FreeSignal (sigbit);
  55.   }
  56. #if !defined (__SASC_60)
  57.   if (DOSBase)
  58.   {
  59.     CloseLibrary ((struct Library *) DOSBase);
  60.   }
  61. #endif
  62. }
  63.  
  64. void
  65. PrintQueue (QHandle *qhandle)
  66. {
  67.   QueueNode *qn = ((QueueHandle *) qhandle) -> qh_QNode;
  68.   QueueHandle *qh = (QueueHandle *) qhandle;
  69.   char s[512], *ptr;
  70.   MyQMessage *msg, *next, *err_msg = NULL;
  71.   int count = 0, replies, qnread;
  72.  
  73.   // ObtainSemaphore (qn -> qn_Semaphore);
  74.   Forbid ();
  75.   ptr = s;
  76.   msg = (MyQMessage *) qn -> qn_List.lh_Head;
  77.   while (next = (MyQMessage *) msg -> qmsg.qm_MinNode.mln_Succ)
  78.   {
  79.     switch (msg -> qmsg.qm_Status)
  80.     {
  81.       case QMS_ACTIVE:
  82.         sprintf (ptr, "[%da:%d],", msg -> pid, msg -> qmsg.qm_Replies); break;
  83.       case QMS_REMOVED:
  84.         sprintf (ptr, "[%dr:%d],", msg -> pid, msg -> qmsg.qm_Replies); break;
  85.       case QMS_MARKER:
  86.         sprintf (ptr, "[m],"); break;
  87.       default:
  88.         sprintf (ptr, "[** %x **],", msg -> qmsg.qm_Status); break;
  89.     }
  90.     if (msg -> qmsg.qm_Status == QMS_ACTIVE ||
  91.         msg -> qmsg.qm_Status == QMS_REMOVED)
  92.     {
  93.       if (msg -> qmsg.qm_Replies > qn -> qn_Read)
  94.         err_msg = msg;
  95.     }
  96.     ptr = s + strlen (s);
  97.     msg = next;
  98.     if (count ++ > 42)
  99.       break;
  100.   }
  101.   if (qh -> qh_Mode == QMODE_LISTEN)
  102.   {
  103.     if (msg = (MyQMessage *) qh -> qh_un.qhl.qhl_Message)
  104.       sprintf (ptr, " current = %d.\n", msg -> pid);
  105.     else
  106.       sprintf (ptr, " current = <null>.\n");
  107.   }
  108.   else
  109.   {
  110.     sprintf (ptr, " qn_Read = %d.\n", qn -> qn_Read);
  111.   }
  112.   if (err_msg)
  113.   {
  114.     replies = err_msg -> qmsg.qm_Replies;
  115.     qnread  = qn -> qn_Read;
  116.   }
  117.   Permit ();
  118.   // ReleaseSemaphore (qn -> qn_Semaphore);
  119.   printf (s);
  120.  
  121.   if (err_msg)
  122.   {
  123.     printf ("\nToo many replies: %d (qn_Read = %d).\n", replies, qnread);            
  124.     while (1)
  125.       Delay (100);
  126.   }
  127. }
  128.  
  129. int
  130. main (int argc, char *argv[])
  131. {
  132.   ULONG sigmask;
  133.   MyQMessage qmsg, *msg = NULL;
  134.   QHandle qh = NULL;
  135.   char *qn, *queuename = "testqueue";
  136.   int r, abort = 0, reopen = 1;
  137.   ULONG pid = 0;
  138.  
  139.   if (argc == 2)
  140.   {
  141.     pid = ((struct Process *) FindTask (0)) -> pr_TaskNum;
  142.     printf ("Server ( pid = %ld ).\n", pid);
  143.   }
  144.   else
  145.     printf ("Client.\n", pid);
  146.  
  147.   if (qn = getenv ("TESTQUEUE"))
  148.   {
  149.     printf ("Queue = %s.\n", qn);
  150.     queuename = qn;
  151.   }
  152.  
  153. #if !defined (__SASC_60)
  154.   SysBase = *(struct ExecBase **)4;
  155.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
  156.     return 1;
  157. #endif
  158.  
  159.   atexit (cleanup);
  160.  
  161.   if ((sigbit = AllocSignal (-1)) == -1)
  162.   {
  163.     printf ("Failed to allocate signal.\n");
  164.     return 1;
  165.   }
  166.   sigmask = 1 << sigbit;
  167.  
  168.   if (!(QueueBase = OpenLibrary ("queue.library", 0)))
  169.   {
  170.     printf ("Failed to open queue.library.\n");
  171.     return 1;
  172.   }
  173.   if (!pid) /* Client */
  174.   {
  175.     r = time (NULL);
  176.     srand (r);
  177.  
  178.     while (1)
  179.     {
  180.       if (!abort && !reopen)
  181.       {
  182.         printf ("Waiting ...\n");
  183.         abort = Wait (sigmask | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
  184.         printf ("Signal.\n");
  185.       }
  186.       if (abort || reopen)
  187.       {
  188.         if (qh)
  189.         {
  190.       Forbid ();
  191.           while (msg = (MyQMessage *) QGetMsg (qh));
  192.       QClose (qh);
  193.       Permit ();
  194.           if (abort)
  195.           {
  196.             printf ("Exiting.\n");
  197.         return 0;
  198.       }
  199.         }
  200.       }
  201.       if (reopen)
  202.       {
  203.     Delay (50);
  204.  
  205.         if (!(qh = QOpen (queuename, QMODE_LISTEN, sigbit)))
  206.         {
  207.           printf ("Failed to open \"%s\" queue.\n", queuename);
  208.           return 1;
  209.         }
  210.         printf ("Queue \"%s\" opened.\n", queuename);
  211.         reopen = 0;
  212.       }
  213.  
  214.       PrintQueue (qh);
  215.  
  216.       if (rand () > RAND_MAX/2) /*** Process all messages ***/
  217.       {
  218.         r = 0;
  219.  
  220.         while (msg = (MyQMessage *) QGetMsg (qh))
  221.         {
  222.       printf ("Got message from %d.\n", msg -> pid);
  223.           r ++;
  224.     }
  225.         if (!r)
  226.           printf ("Got no message(s).\n");
  227.       }
  228.       else /*** Reply one message & block ***/
  229.       {
  230.         if (msg = (MyQMessage *) QGetMsg (qh))
  231.       printf ("Got message from %d (reply, block).\n", msg -> pid);
  232.         else
  233.           printf ("Got no message (reply, block).\n");
  234.  
  235.         if (rand () > RAND_MAX/2)
  236.         {
  237.       QReplyMsg (qh);
  238.           Block (&abort);
  239.         }
  240.         else
  241.         {
  242.           Block (&abort);
  243.       QReplyMsg (qh);
  244.         }
  245.       }
  246. #ifdef LISTEN_REOPEN
  247.       if (rand () < RAND_MAX/10)
  248.         reopen = 1;
  249. #endif
  250.     }
  251.   }
  252.   else
  253.   {
  254.     qmsg.pid = pid;
  255.  
  256.     while (1)
  257.     {
  258.       if (!abort && !reopen)
  259.       {
  260.         printf ("Waiting ...\n");
  261.         abort = Wait (sigmask | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
  262.         printf ("Signal.\n");
  263.       }
  264.       if (abort || reopen) 
  265.       {
  266.         if (qh)
  267.         {
  268.           while ((r = QClose (qh)) > 0)
  269.           {
  270.             printf ("Cannot exit: %d message(s) left in queue.\n", r);
  271.             PrintQueue (qh);
  272.         Delay (10);
  273. #if 1
  274.             if (rand () < RAND_MAX/10)
  275.             {
  276.               printf ("QFlush.\n");
  277.               QFlush (qh);
  278.             }
  279. #endif
  280.             QGetMsg (qh);
  281.           }
  282.           if (abort)
  283.           {
  284.             printf ("All done.\n");
  285.             return 0;
  286.           }
  287.         }
  288.       }
  289.       if (reopen)
  290.       {
  291.         if (!(qh = QOpen (queuename, QMODE_SEND, sigbit)))
  292.         {
  293.           printf ("Failed to open \"%s\" queue.\n", queuename);
  294.           return 1;
  295.         }
  296.         printf ("Queue \"%s\" opened.\n", queuename);
  297.     msg = &qmsg;
  298.         reopen = 0;
  299.       }
  300.       else
  301.       {
  302.         msg = (MyQMessage *) QGetMsg (qh);
  303.         if (msg == &qmsg)
  304.           printf ("Got my message (%d).\n", msg -> pid);
  305.         else if (msg)
  306.           printf ("Got wrong message (%d).\n", msg -> pid);
  307.         else
  308.           printf ("Got no message.\n");
  309.  
  310.         Block (&abort);
  311.       }
  312.       if (!abort)
  313.       {
  314. #ifdef SEND_REOPEN /* ERROR */
  315.         if (rand () < RAND_MAX/10)
  316.           reopen = 1;
  317. #endif
  318.         if (msg == &qmsg)
  319.         {
  320.           printf ("Sending message (%d): ", msg -> pid);
  321.           QAddMsg (qh, (QMessage *) &qmsg);
  322.           PrintQueue (qh);
  323.         }
  324.       }
  325.     }
  326.   }
  327. }
  328.